package com.bjw.ComAssistant;

/**
 * 十六进制工具类
 *
 * @author xpgk xh
 * @date 2024-11-01
 */
public class HexUtil {
    /**
     * 判断一个整数是否为奇数
     *
     * @param number 需要判断的整数
     * @return 如果是奇数返回true，否则返回false
     */
    public static boolean isOdd(int number) {
        // 取模运算：更直观、易读
//        return number % 2 != 0;
        // 位运算：性能稍好
        return (number & 1) == 1;
    }

    /**
     * 判断一个整数是否为偶数
     *
     * @param number 需要判断的整数
     * @return 如果是偶数返回true，否则返回false
     */
    public static boolean isEven(int number) {
        // 取模运算：更直观、易读
//        return number % 2 == 0;
        // 位运算：性能稍好
        return (number & 1) == 0;
    }

    /**
     * 将Hex字符串转换为整数
     *
     * @param hexString 需要转换的Hex字符串
     * @return 转换后的整数
     */
    public static int hexStringToInt(String hexString) {
        if (hexString == null || hexString.isEmpty()) {
            throw new IllegalArgumentException("Hex字符串不能为空");
        }
        return Integer.parseInt(hexString, 16);
    }

    /**
     * 将两位的Hex字符串转换为字节
     *
     * @param hexString 需要转换的两位Hex字符串
     * @return 转换后的字节
     */
    public static byte hexStringToByte(String hexString) {
        if (hexString == null || hexString.length() != 2) {
            throw new IllegalArgumentException("Hex字符串必须是两位");
        }
        return (byte) Integer.parseInt(hexString, 16);
//        return (byte) ((Character.digit(hexString.charAt(0), 16) << 4)
//                + Character.digit(hexString.charAt(1), 16));
    }

    /**
     * 将字节转换为十六进制字符串
     *
     * @param inByte 需要转换的字节
     * @return 转换后的十六进制字符串
     */
    public static String byteToHex(Byte inByte) {
        // 性能相对较低。更简洁且自动补零
//        String hex = String.format("%02x", inByte).toUpperCase();
        // 性能更高但需要手动处理补零逻辑
        String hex = Integer.toHexString(0xFF & inByte);
        if (hex.length() == 1) {
            hex = "0" + hex;
        }
        return hex;
    }

    /**
     * 将字节数组转换为十六进制字符串
     *
     * @param bytes 需要转换的字节数组
     * @return 转换后的十六进制字符串
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            hexString.append(byteToHex(b));
        }
        return hexString.toString();
    }

    /**
     * 将字节数组转换为十六进制字符串，从offset开始，共byteCount个字节
     *
     * @param bytes     需要转换的字节数组
     * @param offset    开始位置的偏移量
     * @param byteCount 需要转换的字节数
     * @return 转换后的十六进制字符串
     */
    public static String bytesToHex(byte[] bytes, int offset, int byteCount) {
        if (bytes == null) {
            throw new IllegalArgumentException("字节数组不能为空");
        }
        if (offset < 0 || byteCount < 0 || offset + byteCount > bytes.length) {
            throw new IllegalArgumentException("无效的偏移量或字节数");
        }
        StringBuilder hexString = new StringBuilder();
        for (int i = offset; i < byteCount; i++) {
            hexString.append(byteToHex(bytes[i]));
        }
        return hexString.toString();
    }

    /**
     * 将字节数组转换为十六进制字符串，并用空格分割
     *
     * @param bytes 需要转换的字节数组
     * @return 转换后的十六进制字符串
     */
    public static String bytesToHexWithSpaces(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            hexString.append(byteToHex(b)).append(" ");
        }
        // 去掉最后一个多余的空格
        if (hexString.length() > 0) {
            hexString.setLength(hexString.length() - 1);
        }
        return hexString.toString();
    }

    /**
     * 将十六进制字符串转换为字节数组
     *
     * @param hexString 需要转换的十六进制字符串
     * @return 转换后的字节数组
     */
    public static byte[] hexStringToBytes(String hexString) {
        int len = hexString.length();
        if (isOdd(len)) {
            hexString = "0" + hexString;
            len++;
        }
        byte[] bytes = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            // 可读性和灵活性更好
//            bytes[i / 2] = hexStringToByte(hexString.substring(i, i + 2));
            // 性能更高
            bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i + 1), 16));
        }
        return bytes;
    }
}